// 1 + 2
const test1 = () => {
    var ast = [{
        type: AstType.ExpressionBinary,
        operator: {
            type: TokenType.plus,
            value: '+',
        },
        left: {
            type: TokenType.number,
            value: 1,
        },
        right: {
            type: TokenType.number,
            value: 2,
        },
    }]
    var output = interpret(ast)
    ensure(3 === output, 'test 1 + 2')
}

// 1 * (2 + 3)
const test2 = () => {
    var ast = [{
        type: AstType.ExpressionBinary,
        operator: {
            type: TokenType.multiply,
            value: '*'
        },
        left: {
            type: TokenType.number,
            value: 1,
        },
        right: {
            type: AstType.ExpressionBinary,
            operator: {
                type: TokenType.plus,
                value: '+'
            },
            left: {
                type: TokenType.number,
                value: 2,
            },
            right: {
                type: TokenType.number,
                value: 3,
            }
        }
    }]

    var output = interpret(ast)
    ensure(5 === output, 'test 1 * (2 + 3)')
}

// (2 - 3) * (2 + 3)
const test3 = () => {
    var ast = [{
        type: AstType.ExpressionBinary,
        operator: {
            type: TokenType.multiply,
            value: '*'
        },
        left: {
            type: AstType.ExpressionBinary,
            operator: {
                type: TokenType.minus,
                value: '-'
            },
            left: {
                type: TokenType.number,
                value: 2,
            },
            right: {
                type: TokenType.number,
                value: 3,
            }
        },
        right: {
            type: AstType.ExpressionBinary,
            operator: {
                type: TokenType.plus,
                value: '+'
            },
            left: {
                type: TokenType.number,
                value: 2,
            },
            right: {
                type: TokenType.number,
                value: 3,
            }
        }
    }]

    var output = interpret(ast)
    ensure(-5 === output, 'test (2 - 3) * (2 + 3)')
}




// var a = 'good'
const testDeclaration01 = () => {
    let ast = [
        {
            type: AstType.DeclarationVariable,
            declarator: {
                type: TokenType.keyword,
                value: 'var',
            },
            variable: {
                type: TokenType.variable,
                value: 'a',
            },
            value: {
                type: TokenType.string,
                value: 'good',
            },
        },
    ]
    interpret(ast)
    let output = valueOf('a')
    let expect = 'good'
    ensure(output === expect, 'testDeclaration01')
}

// var a = 3 + 5
const testDeclaration02 = () => {
    let ast = [
        {
            type: AstType.DeclarationVariable,
            declarator: {
                type: TokenType.keyword,
                value: 'var',
            },
            variable: {
                type: TokenType.variable,
                value: 'a',
            },
            value: {
                type: AstType.ExpressionBinary,
                operator: {
                    type: TokenType.plus,
                    value: '+',
                },
                left: {
                    type: TokenType.number,
                    value: 3,
                },
                right: {
                    type: TokenType.number,
                    value: 5,
                },
            },
        },
    ]
    interpret(ast)
    let output = valueOf('a')
    let expect = 8
    ensure(output === expect, 'testDeclaration02')
}
// if () {}
const test4 = () => {
    var ast = [
        {
            type: AstType.StatementIf,
            // if块运行的条件, 可以是表达式等
            condition: {
                type: TokenType.number,
                value: 1
            },
            // if的condition为true时，执行的作用域
            consequent: {
                type: AstType.StatementBlock,
                body: [
                    {
                        type: AstType.ExpressionBinary,
                        operator: {
                            type: TokenType.plus,
                            value: '+',
                        },
                        left: {
                            type: TokenType.number,
                            value: 1,
                        },
                        right: {
                            type: TokenType.number,
                            value: 2,
                        },
                    }
                ]
            },
            alternate: {}
        }
    ]
    var output = interpret(ast)
    ensure(3 === output, 'if () {}')
}

// if (0) { 1 + 2 } else { 3 + 4 }
const test5 = () => {
    var ast = [
        {
            type: AstType.StatementIf,
            // if块运行的条件, 可以是表达式等
            condition: {
                type: TokenType.number,
                value: 0
            },
            consequent: {
                type: AstType.StatementBlock,
                body: [
                    {
                        type: AstType.ExpressionBinary,
                        operator: {
                            type: TokenType.plus,
                            value: '+',
                        },
                        left: {
                            type: TokenType.number,
                            value: 1,
                        },
                        right: {
                            type: TokenType.number,
                            value: 2,
                        },
                    }
                ]
            },
            alternate: {
                type: AstType.StatementBlock,
                body: [
                    {
                        type: AstType.ExpressionBinary,
                        operator: {
                            type: TokenType.plus,
                            value: '+',
                        },
                        left: {
                            type: TokenType.number,
                            value: 3,
                        },
                        right: {
                            type: TokenType.number,
                            value: 4,
                        },
                    }
                ]
            }
        }
    ]
    var output = interpret(ast)
    ensure(7 === output, 'test if (0) { 1 + 2 } else { 3 + 4 }')
}

const _main = () => {
    // test1()
    // test2()
    // test3()
    testDeclaration01()
}
_main()